<?php
namespace wogu2\mvc\interceptor\http;

use ReflectionClass;
use wogu2\mvc\interceptor\AbstractInterceptor;
use wogu2\mvc\action\ActionInterface;
use wogu2\stdlib\RequestInterface;

class Parameters extends AbstractInterceptor
{
    public function intercept() {
        $config = $this->_runtime->actionConfig;
        $method = $config['method'];
        
        $this->filter($config, $method);
        if(!$this->isValid($config, $method)) {
            $this->_dispatcher->setDispatched(true);
            return ActionInterface::ERROR;
        }
    }
    
    private function filter($config, $method) {
        if(!empty($config['filter-config']['methods'][$method])) {
            $filtersConfig = $config['filter-config'];
            $methodConfig = $filtersConfig['methods'][$method];
            foreach($methodConfig as $fieldName) {
                $field = $filtersConfig['fields'][$fieldName];
                $scope = $field['scope'];
                if('valueStack' == $scope) {
                    $value = $this->get($fieldName);
                } else {
                    $value = $this->_request->getParameter($fieldName, $scope);
                }
                
                if(null !== $value) {
                    $filterClass = new ReflectionClass($field['class']);
                    $filter = $filterClass->newInstance();
                    $setOptionsMethod = $filterClass->getMethod('setOptions');
                    $setOptionsMethod->invoke($filter, $field);
                    $filterMethod = $filterClass->getMethod('filter');
                    $value = $filterMethod->invoke($filter, $value);
                }

                $this->set($fieldName, $value);
            }
        }
    }
    
    private function isValid($config, $method) {
        $bValid = true;
        if(!empty($config['validator-config']['methods'][$method])) {
            $validatorsConfig = $config['validator-config'];
            $methodConfig = $validatorsConfig['methods'][$method];
            foreach($methodConfig as $fieldName) {
                $field = $validatorsConfig['fields'][$fieldName];
                $scope = $field['scope'];
                if('valueStack' == $scope) {
                    $value = $this->get($fieldName);
                } else {
                    $value = $this->_request->getParameter($fieldName, $scope);
                }
                
                if(null !== $value) {
                    $validatorClass = new ReflectionClass($field['class']);
                    $validator = $validatorClass->newInstance();
                    $setOptionsMethod = $validatorClass->getMethod('setOptions');
                    $setOptionsMethod->invoke($validator, $field);
                    $validatorMethod = $validatorClass->getMethod('isValid');
                    if(!$validatorMethod->invoke($validator, $value)) {
                        $bValid = false;
                        
                    }
                }
            }
        }
        
        return $bValid;
    }
}